package com.whnk.pm.service.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.whnk.common.support.Convert;
import com.whnk.pm.domain.BaseInfo;
import com.whnk.pm.domain.IdleResult;
import com.whnk.pm.domain.ImpSignInfo;
import com.whnk.pm.dto.SignExcelDTO;
import com.whnk.pm.mapper.BaseInfoMapper;
import com.whnk.pm.mapper.IdleResultMapper;
import com.whnk.pm.mapper.ImpSignInfoMapper;
import com.whnk.pm.mapper.ProInfoMapper;
import com.whnk.pm.mapper.ProMemMapper;
import com.whnk.pm.mapper.WowInfoMapper;
import com.whnk.pm.service.IImpSignInfoService;

import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;

/**
 * 考勤导入 服务层实现
 *
 * @author whwhnk
 * @date 2019-07-11
 */
@Service
public class ImpSignInfoServiceImpl implements IImpSignInfoService {

    private final Logger logger = LoggerFactory.getLogger(ImpSignInfoServiceImpl.class);

    @Autowired
    private ImpSignInfoMapper impSignInfoMapper;

    @Autowired
    private ProInfoMapper proInfoMapper;
    
    @Autowired
    private ProMemMapper proMemMapper;
    
    @Autowired
	private WowInfoMapper wowInfoMapper;
    
    @Autowired
	private BaseInfoMapper baseInfoMapper;
    
    @Autowired
	private IdleResultMapper idleResultMapper;
    
    /**
     * 查询考勤导入信息
     *
     * @param id 考勤导入ID
     * @return 考勤导入信息
     */
    @Override
    public ImpSignInfo selectImpSignInfoById(Integer id) {
        return impSignInfoMapper.selectImpSignInfoById(id);
    }

    /**
     * 查询考勤导入列表
     *
     * @param impSignInfo 考勤导入信息
     * @return 考勤导入集合
     */
    @Override
    public List<ImpSignInfo> selectImpSignInfoList(ImpSignInfo impSignInfo) {
        return impSignInfoMapper.selectImpSignInfoList(impSignInfo);
    }

    /**
     * 新增考勤导入
     *
     * @param impSignInfo 考勤导入信息
     * @return 结果
     */
    @Override
    public int insertImpSignInfo(ImpSignInfo impSignInfo) {
        return impSignInfoMapper.insertImpSignInfo(impSignInfo);
    }

    /**
     * 修改考勤导入
     *
     * @param impSignInfo 考勤导入信息
     * @return 结果
     */
    @Override
    public int updateImpSignInfo(ImpSignInfo impSignInfo) {
        return impSignInfoMapper.updateImpSignInfo(impSignInfo);
    }

    /**
     * 删除考勤导入对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteImpSignInfoByIds(String ids) {
        return impSignInfoMapper.deleteImpSignInfoByIds(Convert.toStrArray(ids));
    }


    /**
     * 导入考勤
     *
     * @param file
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void signExcelFileUpload(MultipartFile file) throws Exception {
        try (ExcelReader reader = ExcelUtil.getReader(file.getInputStream())) {
            List<Map<String, Object>> mapList = reader.read(7, 8, Integer.MAX_VALUE);
            Gson gson = new GsonBuilder()
                    .setDateFormat("yyyy-MM-dd").create();
            List<SignExcelDTO> signExcelDTOList = mapList.stream()
                    .map(k -> gson.fromJson(gson.toJson(k), SignExcelDTO.class)).collect(Collectors.toList());
            List<ImpSignInfo> signInfoList = new ArrayList<>();
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            signExcelDTOList.forEach(k ->
                {
                    ImpSignInfo signInfo = new ImpSignInfo();
                    BeanUtils.copyProperties(k, signInfo);
                    signInfo.setId(null);
                    try {
                        signInfo.setSignStti(simpleDateFormat.parse(k.getSignStti()));
                        signInfo.setSignEdti(simpleDateFormat.parse(k.getSignEdti()));
                    } catch (ParseException e) {
                        logger.error("format date error -> excel signDate", e);
                    }
                    signInfoList.add(signInfo);
                });
            Date date = new Date();
            for (ImpSignInfo impSignInfo : signInfoList) {
                ImpSignInfo selectImpSignInfo = new ImpSignInfo();
                selectImpSignInfo.setEmpId(impSignInfo.getEmpId());
                selectImpSignInfo.setSignDt(impSignInfo.getSignDt());
                List<ImpSignInfo> impSignInfoList = impSignInfoMapper.selectImpSignInfoList(selectImpSignInfo);
                impSignInfo.setImpTime(date);
                if (impSignInfoList.size() > 0) {
                    logger.info("此用户今日考勤已导入， 更新考勤 " + impSignInfo.getEmpId() + impSignInfo.getSignDt());
                    impSignInfo.setId(impSignInfoList.get(0).getId());
                    impSignInfoMapper.updateImpSignInfo(impSignInfo);
                } else {
                    impSignInfoMapper.insertImpSignInfo(impSignInfo);
                }
            }
        }
    }

    /**
	 * 根据导入的考勤信息新增项目信息
	 */
	@Override
	public int addProsBySign() {
		return proInfoMapper.addProsBySign();
	}
	
	/**
	 * 根据导入的考勤信息新增项目成员信息
	 * 
	 * @return 结果
	 */
	@Override
	public int addProMemsBySign() {
		return proMemMapper.addProMemsBySign();
	}
	
	/**
	 * 根据导入的考勤信息新增项目和成员信息
	 * 
	 */
	@Override
	public void addProsAndMemsBySign() {
		proInfoMapper.addProsBySign();
		proMemMapper.addProMemsBySign();
	}

	/**
	 * 根据导入的考勤信息新增加班信息
	 * 
	 */
	@Override
	public void addWowInfoBySign() {
		wowInfoMapper.addWowInfoBySign();
	}
	
	/**
	 * 根据导入的考勤信息新增人员缺勤信息
	 * 
	 */
	public void addIdleBySign() {
		
		// 1. 查询人员基本信息表
		List<BaseInfo> empInfoList = baseInfoMapper.queryBaseInfoAll();
		
		// 2. 根据人员证件号码到考勤表和日历表中匹配缺勤信息，然后将结果插入人员缺勤信息表
		IdleResult idleResult = null;
		for(BaseInfo empInfo : empInfoList) {
			
			// 设置sql的条件参数
			idleResult = new IdleResult();
			idleResult.setEmpId(empInfo.getEmpId());
			idleResult.setEmpNm(empInfo.getEmpNm());
			idleResult.setCompNm(empInfo.getEmpComp());
			
			// 执行新增缺勤信息的sql语句
			idleResultMapper.addIdleResult(idleResult);
		}
	}
}
